<template>
  <div :style="{position: 'absolute', 'z-index': zIndex, width: maxCanvasInfo.width + 'px', height: maxCanvasInfo.height + 'px'}">
    <div class="contain" :style="getContain">
      <div class="wrap-box" :style="getWrapBox">
        <div class="canvas">
          <img :src="imgUrl" class="canvas-hide" />
        </div>
      </div>
      <div class="drag-box move modal" data-cropper-action="move" :style="getWrapBox" />

      <div class="crop-box" :style="getStyle(imgData.cropBox)" @mousedown.stop.prevent="handleDown">
        <span class="view-box" @mousedown.stop.prevent="handleCanvasDown">
          <img :src="imgUrl" :style="getCropBoxImg" />
        </span>
        <span v-show="showLine" class="dashed dashed-h" />
        <span v-show="showLine" class="dashed dashed-v" />
        <span class="face move" data-cropper-action="move" />
        <span class="line line-e" data-cropper-action="e" />
        <span class="line line-n" data-cropper-action="n" />
        <span class="line line-w" data-cropper-action="w" />
        <span class="line line-s" data-cropper-action="s" />
        <span class="longer longer-e" data-cropper-action="e" />
        <span class="longer longer-n" data-cropper-action="n" />
        <span class="longer longer-w" data-cropper-action="w" />
        <span class="longer longer-s" data-cropper-action="s" />
        <span v-show="!showLine" class="point point-ne" data-cropper-action="ne" />
        <span v-show="!showLine" class="point point-nw" data-cropper-action="nw" />
        <span v-show="!showLine" class="point point-sw" data-cropper-action="sw" />
        <span v-show="!showLine" class="point point-se" data-cropper-action="se" />
      </div>
    </div>
    <div v-show="false && tooltipState" class="tooltip" :style="{top: tooltipStyle.top + 'px', left: tooltipStyle.left + 'px'}">
      <span class="tooltip-btn" :style="{color: disableReset ? '#999' : '#fff'}" @click="resetCropper">重置</span>
      <span class="tooltip-btn" @click="handleCropper(false)">取消</span>
      <span class="tooltip-btn" @click="handleCropper(true)">完成</span>
    </div>
  </div>

</template>

<script>
export default {
  name: 'Cropper',
  props: {
    parentId: {
      type: String,
      default: 'edit'
    },
    imgUrl: {
      type: String,
      default: ''
    },
    zIndex: {
      type: Number,
      default: 999
    },
    cropperInfo: {
      type: Object,
      default: () => {
        return {
          left: 0,
          top: 0,
          width: 0,
          height: 0,
          rotate: 0
        }
      }
    },
    imgInfo: {
      type: Object,
      default: () => {
        return {
          left: 0,
          top: 0,
          width: 0,
          height: 0,
          scaleX: 1,
          scaleY: 1,
          rotate: 0
        }
      }
    },
    // false 非等比的。 true 等比
    type: {
      type: Boolean,
      default: false
    },
    // 非等比的情况下 该参数有效
    maxCanvasInfo: {
      type: Object,
      default: () => {
        return {
          width: 600,
          height: 600
        }
      }
    },
    // 定义 等比缩放情况下，x y 的比例值
    equalRatio: {
      type: Object,
      default: () => {
        return {
          x: 1,
          y: 1
        }
      }
    },
    imgRotate: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      minVal: 20,
      rotate: 0,
      imgData: {
        contain: {
          width: 0,
          height: 0,
          left: 0,
          top: 0
        },
        canvas: {
          left: 0,
          top: 0,
          width: 0,
          height: 0,
          rotate: 0
        },
        cropBox: {
          left: 0,
          top: 0,
          width: 0,
          height: 0
        },
        cropBoxImg: {
          left: 0,
          top: 0
        }
      },
      tooltipStyle: {
        top: -40,
        left: 0
      },
      tooltipState: true,
      disableReset: true,
      showLine: false,
      pagePosition: {},
      rotateScale: 1
    }
  },
  computed: {
    getContain() {
      return {
        ...this.getStyle(this.imgData.contain),
        top: this.imgData.contain.top + 'px',
        left: this.imgData.contain.left + 'px',
        transform: `rotate(${this.rotate || 0}deg)`
      }
    },
    getCropBoxImg() {
      const offsetX = this.imgData.canvas.width * (this.rotateScale - 1) / 2
      const offsetY = this.imgData.canvas.height * (this.rotateScale - 1) / 2
      return {
        width: this.imgData.canvas.width * this.rotateScale + 'px',
        height: this.imgData.canvas.height * this.rotateScale + 'px',
        transform: `translate(${this.imgData.cropBoxImg.left - offsetX}px, ${this.imgData.cropBoxImg.top - offsetY}px) rotate(${this.imgRotate}deg)`
      }

     /* const offsetX = 0
      const offsetY = 0
      return {
        width: this.imgData.canvas.width + 'px',
        height: this.imgData.canvas.height + 'px',
        transform: `translate(${this.imgData.cropBoxImg.left - offsetX}px, ${this.imgData.cropBoxImg.top - offsetY}px) rotate(${this.imgRotate}deg)`
      }*/
    },
    getWrapBox() {
      const { left, top, width, height } = this.imgData.canvas
      const offsetX = width * (this.rotateScale - 1) / 2
      const offsetY = height * (this.rotateScale - 1) / 2
      return {
        width: width * this.rotateScale + 'px',
        height: height * this.rotateScale + 'px',
        transform: `translate(${left - offsetX}px, ${top - offsetY}px) rotate(${this.imgRotate}deg)`
      }

     /* const { left, top, width, height } = this.imgData.canvas
      const offsetX = 0
      const offsetY = 0
      return {
        width: width + 'px',
        height: height + 'px',
        transform: `translate(${left - offsetX}px, ${top - offsetY}px) rotate(${this.imgRotate}deg)`
      }*/
    }
  },
  watch: {
    imgRotate(rotate) {
      const { width: boxWidth, height: boxHeight } = this.imgData.cropBox
      const { left, top, width, height } = this.imgData.canvas

      const hypotenuse = Math.sqrt(boxWidth * boxWidth + boxHeight * boxHeight)
      const halfWidth = boxWidth / 2
      const halfHeight = boxHeight / 2
      const deg = Math.atan(halfWidth / halfHeight) / Math.PI * 180
      let newWidth = Math.sin((deg + Math.abs(rotate)) / 180 * Math.PI) * hypotenuse
      let newHeight = Math.sin((90 - deg + Math.abs(rotate)) / 180 * Math.PI) * hypotenuse

      // 代表框的定位点 也就是左上点
      const centerLT = {
        x: (boxWidth - width) / 2,
        y: (boxHeight - height) / 2
      }
      const moveX = centerLT.x - left
      const moveY = centerLT.y - top
      const absRotate = Math.abs(rotate)
      if (moveX !== 0 && absRotate !== 0) {
        newWidth += Math.abs(moveX) * 2 * Math.cos(absRotate / 180 * Math.PI)
        newHeight += Math.abs(moveX) * 2 * Math.cos(absRotate / 180 * Math.PI)
      }
      if (moveY !== 0) {
        newWidth += Math.abs(moveY) * 2 * Math.sin(absRotate / 180 * Math.PI)
        newHeight += Math.abs(moveY) * 2 * Math.sin(absRotate / 180 * Math.PI)
      }

      const imgScaleX = width / boxWidth
      const imgScaleY = height / boxHeight
      const imgScale = imgScaleX <= imgScaleY ? imgScaleX : imgScaleY

      let scaleX = newWidth / width
      let scaleY = newHeight / boxHeight
      if (boxWidth >= boxHeight) {
        scaleX = newWidth / boxWidth
        scaleY = newHeight / height
      }

      console.log(newWidth, width, imgScale, moveY, moveX)

      const scale = scaleX >= scaleY ? scaleX : scaleY
      if (imgScale >= scale && scale > 1) {
        this.rotateScale = 1
      } else {
        this.rotateScale = scale / imgScale
      }
    }
  },
  mounted() {
    this.setImgData()
    /* eventBus.$on('cover', data => {
       if (data === 'click') {
         /!**
          * 关闭裁剪框时直接裁剪。
          * *!/
         this.handleCropper(true)
       }
     })*/
  },
  methods: {
    /**
     * 取消（false）和确定（true）
     * */
    handleCropper(state) {
      let newCropperInfo = {
        left: this.cropperInfo.left,
        top: this.cropperInfo.top,
        width: this.cropperInfo.width,
        height: this.cropperInfo.height,
        rotate: this.cropperInfo.rotate,
        imgInfo: {
          left: this.imgInfo.left,
          top: this.imgInfo.top,
          width: this.imgInfo.width,
          height: this.imgInfo.height,
          scaleX: this.imgInfo.scaleX,
          scaleY: this.imgInfo.scaleY
        }
      }
      if (state) {
        const newCoordinate = this.getTransformPoint()
        newCropperInfo = {
          left: newCoordinate.x,
          top: newCoordinate.y,
          width: this.imgData.cropBox.width,
          height: this.imgData.cropBox.height,
          rotate: this.cropperInfo.rotate,
          imgInfo: {
            left: this.imgData.cropBoxImg.left,
            top: this.imgData.cropBoxImg.top,
            width: this.imgData.canvas.width / this.imgInfo.scaleX,
            height: this.imgData.canvas.height / this.imgInfo.scaleY,
            scaleX: this.imgInfo.scaleX,
            scaleY: this.imgInfo.scaleY
          }
        }
      }
      this.$emit('handleCropper', newCropperInfo)
    },
    /**
     * 重置
     * */
    resetCropper() {
      this.disableReset = true
      this.setImgData()
    },
    /**
     * 获取获取旋转变换后的left,top
     * */
    getTransformPoint() {
      const newLeftPoint = this.getCenter(
        { x: this.cropperInfo.left + this.imgData.cropBox.left, y: this.cropperInfo.top + this.imgData.cropBox.top },
        {
          x: this.cropperInfo.left + this.cropperInfo.width / 2,
          y: this.cropperInfo.top + this.cropperInfo.height / 2
        },
        this.cropperInfo.rotate
      )
      const center = this.getCenter(
        {
          x: this.cropperInfo.left + this.imgData.cropBox.left + this.imgData.cropBox.width / 2,
          y: this.cropperInfo.top + this.imgData.cropBox.top + this.imgData.cropBox.height / 2
        },
        {
          x: this.cropperInfo.left + this.cropperInfo.width / 2,
          y: this.cropperInfo.top + this.cropperInfo.height / 2
        },
        this.cropperInfo.rotate)
      const newCoordinate = this.getCenter(
        { x: newLeftPoint.x, y: newLeftPoint.y },
        { x: center.x, y: center.y },
        -this.cropperInfo.rotate
      )
      return newCoordinate
    },
    getCenter(point, center, rotate) {
      const deg = Math.PI / 180 * rotate
      const newX = center.x + (point.x - center.x) * Math.cos(deg) - (point.y - center.y) * Math.sin(deg)
      const newY = center.y + (point.x - center.x) * Math.sin(deg) + (point.y - center.y) * Math.cos(deg)
      return {
        x: newX,
        y: newY
      }
    },
    getStyle(styleObj) {
      const needUnitStr = ['width', 'height']
      const style = {}
      for (const key in styleObj) {
        if (needUnitStr.includes(key)) {
          style[key] = styleObj[key] + 'px'
        } else if (key !== 'left' && key !== 'top') {
          style[key] = styleObj[key]
        }
      }
      style.transform = `translate(${styleObj.left}px, ${styleObj.top}px)`
      return style
    },
    setImgData() {
      this.imgData.contain = {
        width: this.cropperInfo.width,
        height: this.cropperInfo.height,
        left: this.cropperInfo.left,
        top: this.cropperInfo.top
      }
      this.imgData.canvas = {
        width: this.imgInfo.width * this.imgInfo.scaleX,
        height: this.imgInfo.height * this.imgInfo.scaleY,
        left: this.imgInfo.left,
        top: this.imgInfo.top
      }
      this.imgData.cropBox = {
        width: this.cropperInfo.width,
        height: this.cropperInfo.height,
        top: 0,
        left: 0
      }
      this.imgData.cropBoxImg = {
        top: this.imgInfo.top,
        left: this.imgInfo.left
      }
      this.rotate = this.cropperInfo.rotate || 0
      this.changeTooltip(this.rotate)
    },
    /**
     * 用于修改tooltip 位置
     * */
    changeTooltip(rotate) {
      const point = this.getTransformPoint()
      const newPoint = this.transform({
        x: point.x,
        y: point.y,
        width: this.imgData.cropBox.width,
        height: this.imgData.cropBox.height
      }, rotate)
      this.tooltipStyle = {
        left: newPoint.left,
        top: newPoint.top - 38
      }
      this.tooltipState = true
    },
    /**
     * crop-box 显示区图片移动
     * */
    handleCanvasDown(e) {
      this.tooltipState = false
      const canvas = { ...this.imgData.canvas }
      const { top, left, width, height } = canvas

      const { top: cTop, left: cLeft, width: cWidth, height: cHeight } = this.imgData.cropBox

      const parentPosition = document.getElementById(this.parentId).getBoundingClientRect()
      const ex = e.pageX - parentPosition.x
      const ey = e.pageY - parentPosition.y

      const move = moveE => {
        this.showLine = true
        this.disableReset = false
        moveE.stopPropagation()
        moveE.preventDefault()
        const currX = moveE.pageX - parentPosition.x
        const currY = moveE.pageY - parentPosition.y
        const skewVal = Math.sqrt(Math.pow(currX - ex, 2) + Math.pow(currY - ey, 2))
        const deg = Math.acos((currX - ex) / skewVal) * 180 / Math.PI
        if (currY - ey > 0) {
          canvas.top = skewVal * Math.sin((deg - this.rotate) * Math.PI / 180) + top
          canvas.left = skewVal * Math.cos((deg - this.rotate) * Math.PI / 180) + left
        } else {
          canvas.top = -skewVal * Math.sin((deg + this.rotate) * Math.PI / 180) + top
          canvas.left = skewVal * Math.cos((deg + this.rotate) * Math.PI / 180) + left
        }

        // 添加移动范围限制
        canvas.left = canvas.left >= cLeft ? cLeft : canvas.left
        canvas.top = canvas.top >= cTop ? cTop : canvas.top
        canvas.left = canvas.left + width >= cLeft + cWidth ? canvas.left : cLeft + cWidth - width
        canvas.top = canvas.top + height >= cTop + cHeight ? canvas.top : cTop + cHeight - height
        this.imgData.canvas = {
          ...canvas
        }
        const newILeft = -cLeft + canvas.left
        const newITop = -cTop + canvas.top
        this.imgData.cropBoxImg = {
          left: newILeft,
          top: newITop
        }
      }
      const up = () => {
        this.showLine = false
        this.changeTooltip(this.rotate)
        document.removeEventListener('mousemove', move, true)
        document.removeEventListener('mouseup', up, true)
      }
      document.addEventListener('mousemove', move, true)
      document.addEventListener('mouseup', up, true)
      return true
    },
    /**
     * 框缩放显示区的图片
     * */
    handleDown(e) {
      this.tooltipState = false
      const cropperAction = e.target.dataset.cropperAction
      // const notDrag = ['move', 'n', 'e', 'w', 's']
      const notDrag = ['move']
      if (cropperAction && notDrag.indexOf(cropperAction) === -1) {
        const hasT = /n/.test(cropperAction)
        const hasB = /s/.test(cropperAction)
        const hasL = /w/.test(cropperAction)
        const hasR = /e/.test(cropperAction)
        const { left, top, width, height } = this.imgData.cropBox
        const { left: cLeft, top: cTop, width: cWidth, height: cHeight } = this.imgData.canvas
        const parentPosition = document.getElementById(this.parentId).getBoundingClientRect()
        const ex = e.pageX - parentPosition.x
        const ey = e.pageY - parentPosition.y

        const move = (moveE) => {
          this.showLine = true
          this.disableReset = false
          const moveX = moveE.pageX - parentPosition.x
          const moveY = moveE.pageY - parentPosition.y
          const offsetX = moveX - ex
          const offsetY = moveY - ey

          if (cropperAction.length === 2) {
            const scale = Math.abs(offsetY / height)
            // state 用于区分是放大还是缩小 true 缩小
            const state = (offsetY < 0 && hasT) || (offsetY >= 0 && hasB)
            let xVal = scale * (state ? cWidth : width)
            let yVal = scale * (state ? cHeight : height)
            let newWidth = state ? cWidth : width
            let newHeight = state ? cHeight : height
            newWidth = newWidth * (1 - scale)
            newHeight = newHeight * (1 - scale)

            // 限制最小宽高
            if (!state) {
              if (width - xVal < this.minVal) {
                newWidth = this.minVal
                newHeight = this.minVal / width * height
              }

              if (height - yVal < this.minVal) {
                newWidth = this.minVal / height * width
                newHeight = this.minVal
              }

              if (width - xVal < this.minVal && height - yVal < this.minVal) {
                if (width >= height) {
                  newWidth = this.minVal / height * width
                  newHeight = this.minVal
                } else {
                  newWidth = this.minVal
                  newHeight = this.minVal / width * height
                }
              }
              xVal = width - newWidth
              yVal = height - newHeight
            }

            let newTop = state ? cTop : top
            let newLeft = state ? cLeft : left

            const positionState = (offsetY > 0 && state) || (offsetY < 0 && !state)
            if (hasL && hasT) {
              newLeft = newLeft + (positionState ? -xVal : xVal)
              newTop = newTop + (positionState ? -yVal : yVal)
            }
            if (hasL && hasB) {
              newLeft = newLeft + (positionState ? xVal : -xVal)
            }
            if (hasR && hasT) {
              newTop = newTop + (positionState ? -yVal : yVal)
            }

            if (state) {
              this.updateDate('canvas', { left: newLeft, top: newTop, width: newWidth, height: newHeight })
              this.updateDate('cropBoxImg', { left: newLeft, top: newTop })
            } else {
              this.updateDate('cropBox', { left: newLeft, top: newTop, width: newWidth, height: newHeight })
              this.updateDate('cropBoxImg', { left: cLeft - newLeft, top: cTop - newTop })
            }
          } else {
            if (this.type) {
              // 确定是放大还是缩小 true 缩小
              const state = (hasT && offsetY < 0) || (hasB && offsetY > 0) || (hasL && offsetX < 0) || (hasR && offsetX > 0)
              let newWidth = state ? cWidth : width
              let newHeight = state ? cHeight : height
              let newTop = state ? cTop : top
              let newLeft = state ? cLeft : left

              const newOffsetY = Math.abs(offsetY)
              const newOffsetX = Math.abs(offsetX)
              if (hasT) {
                const scale = newWidth / newHeight
                newHeight -= newOffsetY
                newWidth -= newOffsetY * scale
                newLeft += newOffsetY * scale / 2
                newTop += newOffsetY
              }
              if (hasB) {
                const scale = newWidth / newHeight
                newHeight -= newOffsetY
                newWidth -= newOffsetY * scale
                newLeft += newOffsetY * scale / 2
              }
              if (hasL) {
                const scale = newWidth / newHeight
                newHeight -= newOffsetX / scale
                newWidth -= newOffsetX
                newLeft += newOffsetX
                newTop += newOffsetX / scale / 2
              }
              if (hasR) {
                const scale = newWidth / newHeight
                newHeight -= newOffsetX / scale
                newWidth -= newOffsetX
                newTop += newOffsetX / scale / 2
              }

              if (state) {
                this.updateDate('canvas', { left: newLeft, top: newTop, width: newWidth, height: newHeight })
                this.updateDate('cropBoxImg', { left: newLeft, top: newTop })
              } else {
                this.updateDate('cropBox', { left: newLeft, top: newTop, width: newWidth, height: newHeight })
                this.updateDate('cropBoxImg', { left: cLeft - newLeft, top: cTop - newTop })
              }
            } else {
              console.log('非等缩放==============')
              /* let newTop = top
              let newLeft = left
              let newWidth = width
              let newHeight = height
              if (hasT) {
                newHeight -= offsetY
                newTop += offsetY
                newTop = newTop <= 0 ? 0 : newTop
              }
              if (hasB) {
                newHeight += offsetY
              }
              if (hasL) {
                newLeft += offsetX
                if (newLeft <= 0) {
                  if (newLeft < -this.imgData.contain.left) {
                    newLeft = -this.imgData.contain.left
                  }
                } else {
                  if (newLeft > left + width - this.minVal) {
                    newLeft = left + width - this.minVal
                  }
                }
                // newLeft = newLeft <= 0 ? (newLeft < -this.imgData.contain.left ? -this.imgData.contain.left : newLeft) : (newLeft < left + width - this.minVal ? newLeft : left + width - this.minVal)
                newWidth -= newLeft - left
                this.imgData.contain.width = newWidth
                this.imgData.contain.left = (this.maxCanvasInfo.width - newWidth) / 2
              }
              if (hasR) {
                const newOffset = width + offsetX > this.minVal ? offsetX : this.minVal - width
                newWidth += newOffset
              }
              this.updateDate('cropBox', { left: newLeft, top: newTop, width: newWidth, height: newHeight })
              this.updateDate('cropBoxImg', { left: cLeft - newLeft, top: cTop - newTop })*/

              // this.imgData.contain.width = newWidth
              // this.imgData.contain.height = containH + offsetY
            }
          }
        }
        const up = () => {
          this.showLine = false
          this.changeTooltip(this.rotate)
          document.removeEventListener('mousemove', move)
          document.removeEventListener('mouseup', up)

          if ((this.type && cropperAction.length === 1) || cropperAction.length === 2) {
            const { width, height } = this.imgData.contain
            let scale = width / this.imgData.cropBox.width
            const { width: cWidth, height: cHeight } = this.imgData.canvas
            const boxScale = width / height
            const canvasScale = cWidth / cHeight
            // false 缩小 true 放大
            let reduce = false
            if (boxScale >= canvasScale) {
              if (scale * cWidth < width) {
                scale = width / cWidth
              }
              if (cWidth < this.imgData.cropBox.width) {
                reduce = true
              }
            } else {
              if (scale * cHeight <= height) {
                scale = height / cHeight
              }
              if (cHeight < this.imgData.cropBox.height) {
                reduce = true
              }
            }

            let newLeft = this.imgData.cropBoxImg.left * scale
            let newTop = this.imgData.cropBoxImg.top * scale

            if (reduce) {
              if (cropperAction.length === 1) {
                newLeft = this.imgData.cropBoxImg.left + (hasT || hasB ? cWidth * (1 - scale) / 2 : cWidth * (1 - scale))
                newTop = this.imgData.cropBoxImg.top + (hasL || hasR ? cHeight * (1 - scale) / 2 : cHeight * (1 - scale))
                if (hasR) {
                  newLeft = this.imgData.cropBoxImg.left
                }
                if (hasB) {
                  newTop = this.imgData.cropBoxImg.top
                }
              } else {
                // cropperAction.length === 2
                newLeft = this.imgData.cropBoxImg.left
                newTop = this.imgData.cropBoxImg.top
                if (hasT && hasL) {
                  newLeft = this.imgData.cropBoxImg.left + cWidth * (1 - scale)
                  newTop = this.imgData.cropBoxImg.top + cHeight * (1 - scale)
                }
                if (hasL && hasB) {
                  newLeft = this.imgData.cropBoxImg.left + cWidth * (1 - scale)
                }
                if (hasR && hasT) {
                  newTop = this.imgData.cropBoxImg.top + cHeight * (1 - scale)
                }
              }
            } else {
              this.updateDate('cropBox', { left: 0, top: 0, width, height })
            }
            const newWidth = scale * cWidth
            const newHeight = scale * cHeight
            newLeft = newLeft > 0 ? 0 : (width - newWidth > newLeft ? width - newWidth : newLeft)
            newTop = newTop > 0 ? 0 : (height - newHeight > newTop ? height - newHeight : newTop)

            this.updateDate('canvas', { left: newLeft, top: newTop, width: newWidth, height: newHeight })
            this.updateDate('cropBoxImg', { left: newLeft, top: newTop })
          }
        }
        document.addEventListener('mousemove', move)
        document.addEventListener('mouseup', up)
      }
    },
    /**
     * 获取旋转指定角度后的rect
     * @param  {[type]} options rect
     * @param  {[type]} angle   旋转角度
     * @return {[type]}
     */
    transform(options, angle) {
      const x = options.x
      const y = options.y
      const width = options.width
      const height = options.height

      const r = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)) / 2
      const a = Math.round(Math.atan(height / width) * 180 / Math.PI)
      const tlbra = 180 - angle - a
      const trbla = a - angle
      const ta = 90 - angle
      const ra = angle

      const halfWidth = width / 2
      const halfHeight = height / 2

      const middleX = x + halfWidth
      const middleY = y + halfHeight

      const topLeft = {
        x: middleX + r * Math.cos(tlbra * Math.PI / 180),
        y: middleY - r * Math.sin(tlbra * Math.PI / 180)
      }
      const top = {
        x: middleX + halfHeight * Math.cos(ta * Math.PI / 180),
        y: middleY - halfHeight * Math.sin(ta * Math.PI / 180)
      }
      const topRight = {
        x: middleX + r * Math.cos(trbla * Math.PI / 180),
        y: middleY - r * Math.sin(trbla * Math.PI / 180)
      }
      const right = {
        x: middleX + halfWidth * Math.cos(ra * Math.PI / 180),
        y: middleY + halfWidth * Math.sin(ra * Math.PI / 180)
      }
      const bottomRight = {
        x: middleX - r * Math.cos(tlbra * Math.PI / 180),
        y: middleY + r * Math.sin(tlbra * Math.PI / 180)
      }
      const bottom = {
        x: middleX - halfHeight * Math.sin(ra * Math.PI / 180),
        y: middleY + halfHeight * Math.cos(ra * Math.PI / 180)
      }
      const bottomLeft = {
        x: middleX - r * Math.cos(trbla * Math.PI / 180),
        y: middleY + r * Math.sin(trbla * Math.PI / 180)
      }
      const left = {
        x: middleX - halfWidth * Math.cos(ra * Math.PI / 180),
        y: middleY - halfWidth * Math.sin(ra * Math.PI / 180)
      }
      const minX = Math.min(topLeft.x, topRight.x, bottomRight.x, bottomLeft.x)
      const maxX = Math.max(topLeft.x, topRight.x, bottomRight.x, bottomLeft.x)
      const minY = Math.min(topLeft.y, topRight.y, bottomRight.y, bottomLeft.y)
      const maxY = Math.max(topLeft.y, topRight.y, bottomRight.y, bottomLeft.y)
      return {
        point: [topLeft, top, topRight, right, bottomRight, bottom, bottomLeft, left],
        width: maxX - minX,
        height: maxY - minY,
        left: minX,
        right: maxX,
        top: minY,
        bottom: maxY
      }
    },
    updateDate(type, { width, height, left, top }) {
      if (type === 'canvas') {
        this.imgData.canvas = {
          left,
          top,
          width,
          height
        }
      }
      if (type === 'cropBox') {
        this.imgData.cropBox = {
          left,
          top,
          width,
          height
        }
      }
      if (type === 'cropBoxImg') {
        this.imgData.cropBoxImg = {
          left,
          top
        }
      }
    }
  }

}
</script>

<style lang="scss" scoped>
.contain {
  direction: ltr;
  font-size: 0;
  line-height: 0;
  position: absolute;

  .wrap-box, .canvas {
    overflow: hidden;
  }

  .canvas-hide {
    display: block;
    height: 100%;
    position: absolute;
    width: 100%;
  }

  .move {
    cursor: move;
    pointer-events: none;
  }

  .modal {
    background-color: #222;
    opacity: 0.7;
  }

  .crop-box, .border-box {
    .view-box {
      display: block;
      height: 100%;
      border: 1px solid #fff;
      box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.3);
      overflow: hidden;
      width: 100%;
    }

    .dashed {
      border: 0 solid #fff;
      display: block;
      opacity: 1;
      position: absolute;
      pointer-events: none;

      &.dashed-h {
        border-bottom-width: 1px;
        border-top-width: 1px;
        height: calc(100% / 3);
        left: 0;
        top: calc(100% / 3);
        width: 100%;
      }

      &.dashed-v {
        border-left-width: 1px;
        border-right-width: 1px;
        height: 100%;
        left: calc(100% / 3);
        top: 0;
        width: calc(100% / 3);
      }
    }

    .face, .line, .point, .border-point {
      display: block;
      height: 100%;
      opacity: 0.1;
      position: absolute;
      width: 100%;
    }

    .face {
      background-color: #fff;
      left: 0;
      top: 0;
    }

    .line {
      &.line-e {
        cursor: ew-resize;
        right: -3px;
        top: 0;
        width: 5px
      }

      &.line-n {
        cursor: ns-resize;
        height: 5px;
        left: 0;
        top: -3px;
      }

      &.line-w {
        cursor: ew-resize;
        left: -3px;
        top: 0;
        width: 5px;
      }

      &.line-s {
        bottom: -3px;
        cursor: ns-resize;
        height: 5px;
        left: 0;
      }
    }

    .border-point {
      width: 14px;
      height: 14px;
      opacity: 1;
      border-radius: 50%;
      background: #fff;
      border: 1px solid #C6C9CF;

      &.border-point-ne {
        cursor: nesw-resize;
        right: -7px;
        top: -7px;
      }

      &.border-point-nw {
        cursor: nwse-resize;
        left: -7px;
        top: -7px;
      }

      &.border-point-se {
        cursor: nwse-resize;
        right: -7px;
        bottom: -7px;
      }

      &.border-point-sw {
        bottom: -7px;
        cursor: nesw-resize;
        left: -7px;
      }
    }

    .point {
      height: 9px;
      opacity: 1;
      width: 9px;
      border: 2px solid #fff;

      &.point-ne {
        cursor: nesw-resize;
        right: -2px;
        top: -2px;
        border-style: solid solid none none;
      }

      &.point-nw {
        cursor: nwse-resize;
        left: -2px;
        top: -2px;
        border-style: solid none none solid;
      }

      &.point-sw {
        bottom: -2px;
        cursor: nesw-resize;
        left: -2px;
        border-style: none none solid solid;
      }

      &.point-se {
        bottom: -2px;
        cursor: nwse-resize;
        right: -2px;
        border-style: none solid solid none;
      }
    }

    .longer {
      position: absolute;
      background: #fff;
      border-radius: 4px;

      &.longer-e {
        cursor: ew-resize;
        height: 22px;
        width: 5px;
        top: 50%;
        right: -2px;
        margin-top: -11px;
      }

      &.longer-n {
        cursor: ns-resize;
        height: 5px;
        width: 22px;
        top: -2px;
        left: 50%;
        margin-left: -11px;
      }

      &.longer-w {
        cursor: ew-resize;
        height: 22px;
        width: 5px;
        top: 50%;
        left: -2px;
        margin-top: -11px;
      }

      &.longer-s {
        cursor: ns-resize;
        height: 5px;
        width: 22px;
        bottom: -2px;
        left: 50%;
        margin-left: -11px;
      }
    }
  }

  .border-box {
    box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.3);
    border: 2px solid #FFFFFF;
  }

  .wrap-box, .canvas, .border-box, .drag-box, .crop-box, .modal {
    bottom: 0;
    left: 0;
    position: absolute;
    right: 0;
    top: 0;
  }

  img {
    display: block;
    image-orientation: 0deg;
    max-height: none !important;
    max-width: none !important;
    min-height: 0 !important;
    min-width: 0 !important;
    width: 100%;
    height: 100%;
  }
}

.tooltip {
  position: absolute;
  z-index: 9999;
  clear: both;
  cursor: default;
  width: 211px;
  height: 48px;
  background: #444444;
  box-shadow: 0 5px 12px 4px rgba(0, 0, 0, 0.09);
  border-radius: 4px;
  padding: 12px 0;

  &-btn {
    display: inline-block;
    background: none;
    border-right: 1px solid #666;
    color: #fff;
    cursor: pointer;
    outline: 0;
    position: relative;
    white-space: nowrap;
    vertical-align: top;
    text-align: center;
    -webkit-appearance: none;
    width: 67px;
    height: 24px;
    line-height: 24px;
    font-size: 15px;

    &:last-child {
      border: none;
    }
  }
}
</style>

